package com.airlenet.codetoword;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/**
 * 代码分析器 - 用于扫描和分析代码文件
 * 版权所有 © 2024 Airlenet. 保留所有权利。
 */
public class CodeAnalyzer {
    private List<CodeFile> codeFiles;
    
    public CodeAnalyzer() {
        this.codeFiles = new ArrayList<>();
    }
    
    /**
     * 分析指定目录中的代码文件
     */
    public List<CodeFile> analyzeDirectory(Path directory) throws IOException {
        codeFiles.clear();
        System.out.println("正在分析目录: " + directory);
        scanDirectory(directory);
        System.out.println("找到 " + codeFiles.size() + " 个代码文件");
        return codeFiles;
    }
    
    private void scanDirectory(Path directory) throws IOException {
        try {
            Files.walk(directory)
                .filter(path -> {
                    try {
                        return !isExcludedDirectory(path) && Files.isRegularFile(path);
                    } catch (Exception e) {
                        // 跳过无法访问的文件或目录
                        System.err.println("跳过无法访问的文件: " + path + " - " + e.getMessage());
                        return false;
                    }
                })
                .filter(this::isCodeFile)
                .forEach(file -> {
                    try {
                        CodeFile codeFile = readCodeFile(file);
                        codeFiles.add(codeFile);
                    } catch (IOException e) {
                        System.err.println("读取文件失败: " + file + " - " + e.getMessage());
                    } catch (Exception e) {
                        System.err.println("处理文件失败: " + file + " - " + e.getMessage());
                    }
                });
        } catch (Exception e) {
            System.err.println("扫描目录时发生错误: " + directory + " - " + e.getMessage());
            // 继续处理，不抛出异常
        }
    }
    
    private boolean isExcludedDirectory(Path path) {
        String pathStr = path.toString().toLowerCase();
        // 排除常见的不需要扫描的目录
        return pathStr.contains("\\.idea") || 
               pathStr.contains("\\.codebuddy") ||
               pathStr.contains("\\.vscode") ||
               pathStr.contains("\\uni_modules") ||
               pathStr.contains("\\node_modules") ||
               pathStr.contains("\\.pnpm") ||
               pathStr.contains("\\target") ||
               pathStr.contains("\\build") ||
               pathStr.contains("\\.git") ||
               pathStr.contains("\\dist") ||
               pathStr.contains("\\logs") ||
               pathStr.contains("\\temp");
    }
    
    private boolean isCodeFile(Path file) {
        String fileName = file.getFileName().toString().toLowerCase();
        return fileName.endsWith(".java") ||
               fileName.endsWith(".py") ||
               fileName.endsWith(".js") ||
               fileName.endsWith(".ts") ||
               fileName.endsWith(".html") ||
               fileName.endsWith(".css") ||
               fileName.endsWith(".xml") ||
               fileName.endsWith(".properties") ||
               fileName.endsWith(".yml") ||
               fileName.endsWith(".yaml") ||
               fileName.endsWith(".json") ||
               fileName.endsWith(".md") ||
               fileName.endsWith(".txt");
    }
    
    private CodeFile readCodeFile(Path file) throws IOException {
        String content = Files.readString(file);
        String relativePath = file.toString().replace(file.getFileSystem().getRootDirectories().iterator().next().toString(), "");
        
        return new CodeFile(
            file.getFileName().toString(),
            file.toString(),
            relativePath,
            content,
            getFileType(file.getFileName().toString()),
            countLines(content)
        );
    }
    
    private String getFileType(String fileName) {
        if (fileName.endsWith(".java")) return "Java";
        if (fileName.endsWith(".py")) return "Python";
        if (fileName.endsWith(".js")) return "JavaScript";
        if (fileName.endsWith(".ts")) return "TypeScript";
        if (fileName.endsWith(".html")) return "HTML";
        if (fileName.endsWith(".css")) return "CSS";
        if (fileName.endsWith(".xml")) return "XML";
        if (fileName.endsWith(".properties")) return "Properties";
        if (fileName.endsWith(".yml") || fileName.endsWith(".yaml")) return "YAML";
        if (fileName.endsWith(".json")) return "JSON";
        if (fileName.endsWith(".md")) return "Markdown";
        if (fileName.endsWith(".txt")) return "Text";
        return "Other";
    }
    
    private int countLines(String content) {
        if (content == null || content.isEmpty()) {
            return 0;
        }
        return content.split("\r\n|\r|\n").length;
    }
}